<?php
namespace app\modules\admin\controllers;

use app\models\Manager;
use app\models\ManagerLog;
use app\models\ManagerRole;
use app\models\RbacManager;
use app\models\RbacPermission;
use Yii;
use yii\data\Pagination;
use yii\helpers\Url;
use yii\web\ForbiddenHttpException;
use yii\web\NotFoundHttpException;

/**
 * 权限管理
 *
 * Class RbacController
 * @package app\modules\admin\controllers
 */
class RbacController extends BaseController
{
    /**
     * 管理员管理
     * @throws ForbiddenHttpException
     * @return string
     */
    public function actionManager()
    {
        if (!$this->manager->can('rbac/manager')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $query = Manager::find()->andWhere(['>', 'id', 1])->andWhere(['<>', 'status', Manager::STATUS_DELETED]);
        $query->andFilterWhere([
            'like',
            'username',
            Yii::$app->request->get('search_username')
        ]);
        $pagination = new Pagination(['totalCount'=>$query->count()]);
        $model_list = $query->orderBy('create_time DESC')->offset($pagination->offset)->limit($pagination->limit)->all();
        return $this->render('manager', [
            'model_list'=>$model_list,
            'pagination'=>$pagination
        ]);
    }

    /**
     * 添加/修改管理员
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return string
     */
    public function actionEditManager()
    {
        if (!$this->manager->can('rbac/manager')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $id = Yii::$app->request->get('id');
        if ($this->isPost()) {
            $id = isset(Yii::$app->request->post('Manager')['id']) ? Yii::$app->request->post('Manager')['id'] : 0;
        }
        if ($id > 0) {
            $model = Manager::findOne($id);
            if (empty($model)) {
                throw new NotFoundHttpException('没有找到管理员信息。');
            }
            if ($model->rid == 1) {
                throw new ForbiddenHttpException('不能修改系统管理员。');
            }
        } else {
            $model = new Manager();
            $model->create_time = time();
        }
        if ($model->load(Yii::$app->request->post())) {
            if (!empty(Yii::$app->request->post('Manager')) && !empty(Yii::$app->request->post('Manager')['password'])) {
                $model->password = Yii::$app->security->generatePasswordHash(Yii::$app->request->post('Manager')['password']);
            }
            if ($model->isNewRecord && empty($model->password)) {
                $model->addError('password', 'Password cannot be empty.');
            } else {
                if ($model->save()) {
                    $authManager = Yii::$app->authManager;
                    if (isset($model->oldAttributes) && !empty($model->oldAttributes['rid'])) {
                        $old_role = RbacManager::getAuthRole('role_' . $model->oldAttributes['rid']);
                        if (!empty($old_role)) {
                            $authManager->revoke($old_role, $model->id);
                        }
                    }
                    $role = RbacManager::getAuthRole('role_' . $model->rid);
                    if (!empty($role)) {
                        $authManager->assign($role, $model->id);
                    }
                    ManagerLog::info($this->manager->id, '', '保存管理员：' . print_r($model->attributes, true));
                    Yii::$app->session->addFlash('success', '数据已保存。');
                    Yii::$app->session->setFlash('redirect', json_encode([
                        'url'=>Url::to(['/admin/rbac/manager']),
                        'txt'=>'List Managers'
                    ]));
                }
            }
        }
        return $this->render('manager_edit', [
            'model'=>$model
        ]);
    }

    /**
     * 删除管理员AJAX接口
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return array
     */
    public function actionDeleteManager()
    {
        if (!$this->manager->can('rbac/manager')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $id = Yii::$app->request->get('id');
        $model = Manager::findOne($id);
        if (empty($model)) {
            throw new NotFoundHttpException('没有找到管理员。');
        }
        if ($model->rid == 1) {
            throw new ForbiddenHttpException('不能删除系统管理员。');
        }
        $model->status = Manager::STATUS_DELETED;
        if ($model->save()) {
            ManagerLog::info($this->manager->id, '', '删除管理员：' . $model->id);
            return ['result'=>true];
        }
        return ['message'=>'删除失败。', 'errors'=>$model->errors];
    }

    /**
     * 切换管理员状态AJAX接口
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return array
     */
    public function actionSetStatus()
    {
        if (!$this->manager->can('rbac/manager')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $id = Yii::$app->request->get('id');
        $model = Manager::findOne($id);
        if (empty($model)) {
            throw new NotFoundHttpException('没有找到管理员。');
        }
        if ($model->rid == 1) {
            throw new ForbiddenHttpException('不能设置系统管理员。');
        }
        $model->status = [Manager::STATUS_ACTIVE=>Manager::STATUS_STOPED, Manager::STATUS_STOPED=>Manager::STATUS_ACTIVE][$model->status];
        if ($model->save()) {
            ManagerLog::info($this->manager->id, '', '修改管理员：' . $model->id . '状态' . $model->status);
            return ['result'=>'success'];
        } else {
            return ['message'=>'操作失败。', 'errors'=>$model->errors];
        }
    }

    /**
     * 角色管理
     * @throws ForbiddenHttpException
     * @return string
     */
    public function actionRole()
    {
        if (!$this->manager->can('rbac/role')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $query = ManagerRole::find()->where(['>', 'id', 1]);
        $model_list = $query->all();
        return $this->render('role', [
            'model_list'=>$model_list
        ]);
    }

    /**
     * 添加/修改角色
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return string
     */
    public function actionEditRole()
    {
        if (!$this->manager->can('rbac/role')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $id = Yii::$app->request->get('id');
        if ($this->isPost()) {
            $id = isset(Yii::$app->request->post('ManagerRole')['id']) ? Yii::$app->request->post('ManagerRole')['id'] : 0;
        }
        if ($id > 0) {
            $model = ManagerRole::findOne($id);
            if (empty($model)) {
                throw new NotFoundHttpException('没有找到管理角色。');
            }
            if ($model->id == 1) {
                throw new ForbiddenHttpException('不能修改系统管理员角色。');
            }
        } else {
            $model = new ManagerRole();
        }
        if ($model->load(Yii::$app->request->post()) && $model->validate()) {
            if ($model->save()) {
                // 保存权限 开始
                RbacManager::removeAuthItem('role_' . $model->id);
                $auth_list = Yii::$app->request->post('auth');
                $authManager = Yii::$app->authManager;
                $auth_role = $authManager->createRole('role_' . $model->id);
                $auth_role->description = $model->name . ':' . $model->remark;
                $authManager->add($auth_role);
                if (!empty($auth_list) && is_array($auth_list)) {
                    foreach ($auth_list as $item_name) {
                        $auth_item = RbacManager::getAuthItem($item_name);
                        if (!empty($auth_item)) {
                            $authManager->addChild($auth_role, $auth_item);
                        }
                    }
                }
                // 保存权限 结束
                ManagerLog::info($this->manager->id, '', '保存角色：' . print_r($model->attributes, true));
                Yii::$app->session->addFlash('success', '数据已保存。');
            }
        }
        return $this->render('role_edit', [
            'model'=>$model
        ]);
    }

    /**
     * 删除角色AJAX接口
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return array
     */
    public function actionDeleteRole()
    {
        if (!$this->manager->can('rbac/role')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $id = Yii::$app->request->get('id');
        $model = ManagerRole::findOne($id);
        if (empty($model)) {
            throw new NotFoundHttpException('没有找到管理员角色。');
        }
        if ($model->id == 1) {
            throw new ForbiddenHttpException('不能删除系统管理员角色。');
        }
        if ($model->delete()) {
            RbacManager::removeAuthItem('role_' . $model->id);
            ManagerLog::info($this->manager->id, '', '删除角色:' . print_r($model->attributes, true));
            return ['result'=>'success'];
        }
        return ['message'=>'删除失败。', 'errors'=>$model->errors];
    }

    /**
     * 权限列表
     * @throws ForbiddenHttpException
     * @return string
     */
    public function actionItem()
    {
        if (!$this->manager->can('rbac/item')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        return $this->render('item_list');
    }

    /**
     * 添加权限
     * @throws ForbiddenHttpException
     * @return string
     */
    public function actionEditItem()
    {
        if (!$this->manager->can('rbac/item')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $model = new RbacPermission();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            ManagerLog::info($this->manager->id, '', '保存权限：' . print_r($model->attributes, true));
            Yii::$app->session->addFlash('success', '数据已保存。');
        }
        return $this->render('item_edit', [
            'model'=>$model
        ]);
    }

    /**
     * 删除权限AJAX接口
     * @param integer $name 权限名称
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return array
     */
    public function actionDeleteItem($name)
    {
        if (!$this->manager->can('rbac/item')) {
            throw new ForbiddenHttpException('没有权限。');
        }
        $authManager = Yii::$app->authManager;
        $item = $authManager->getPermission($name);
        if (empty($item)) {
            throw new NotFoundHttpException('没有找到权限信息。');
        }
        if (!$authManager->remove($item)) {
            return ['message'=>'无法删除权限。'];
        }
        ManagerLog::info($this->manager->id, '', '删除权限:' . $item->name . ':' . $item->description);
        return ['result'=>'success'];
    }

    /**
     * 管理员日志
     * @throws ForbiddenHttpException
     * @throws NotFoundHttpException
     * @return string
     */
    public function actionLog()
    {
        if (!$this->manager->can('rbac/log')) {
            throw new ForbiddenHttpException('Forbidden.');
        }
        $query = ManagerLog::find();
        if (!empty(Yii::$app->request->get('search_username'))) {
            /* @var $search_manager Manager */
            $search_manager = Manager::find()->where(['like', 'username', Yii::$app->request->get('search_username')])->one();
            if (empty($search_manager)) {
                throw new NotFoundHttpException('没有找到管理用户：' . Yii::$app->request->get('search_username'));
            }
            $query->andWhere(['mid'=>$search_manager->id]);
        }
        $search_start_time = Yii::$app->request->get('search_start_time');
        if (!empty($search_start_time)) {
            $search_start_time = strtotime($search_start_time);
            $query->andFilterWhere(['>=', 'time', $search_start_time]);
        }
        $search_end_time = Yii::$app->request->get('search_end_time');
        if (!empty($search_end_time)) {
            $search_end_time = strtotime($search_end_time . ' 23:59:59');
            $query->andFilterWhere(['<=', 'time', $search_end_time]);
        }
        $pagination = new Pagination(['totalCount'=>$query->count()]);
        $model_list = $query->orderBy('time DESC')->offset($pagination->offset)->limit($pagination->limit)->all();
        return $this->render('log', [
            'model_list'=>$model_list,
            'pagination'=>$pagination
        ]);
    }
}
